#include "ticket.h"
#include "ticket_p.h"
#include "ticketchangeset.h"

#include <QtCore/QVariant>
#include <QtCore/QObject>
#include <QtCore/QStringList>

TicketEditorPrivate::TicketEditorPrivate()
    : TicketEditor(), m_ticket(0), m_temp(new TicketPrivate(0))
{

}

TicketEditorPrivate::TicketEditorPrivate(Ticket *ticket)
    : TicketEditor()
{
    m_temp = new TicketPrivate(0);
    if ((m_ticket = qobject_cast<TicketPrivate *>(ticket)) == 0)
        qWarning("TicketEditorPrivate: Could not convert ticket to TicketPrivate");
    else
        copyTicketDetails(m_ticket, m_temp);
}

TicketEditorPrivate::~TicketEditorPrivate()
{
    m_temp->m_changesets.clear();
    delete m_temp;
}

void TicketEditorPrivate::copyTicketDetails(const TicketPrivate * const src, TicketPrivate *dest)
{
    dest->m_id = src->m_id;
    dest->m_created = src->m_created;
    dest->m_modified = src->m_modified;
    dest->m_fields = src->m_fields;
    dest->m_changesets = src->m_changesets;
}

void TicketEditorPrivate::setFieldByName(const QString &fieldName, const QVariant &value)
{
    m_temp->m_fields[fieldName] = value;
}

void TicketEditorPrivate::setId(int id)
{
    m_temp->m_id = id;
}

void TicketEditorPrivate::setCreated(QDateTime created)
{
    m_temp->m_created = created;
}

void TicketEditorPrivate::setModified(QDateTime modified)
{
    m_temp->m_modified = modified;
}

void TicketEditorPrivate::save(const QString &comment)
{
    copyTicketDetails(m_temp, m_ticket);
    m_ticket->save(comment);
}


void TicketEditorPrivate::update()
{
    copyTicketDetails(m_temp, m_ticket);
    m_ticket->doUpdateNotify();
}

TicketPrivate::TicketPrivate(TicketExplorerBackendContext *ctx)
    : m_id(-1), m_created(QDateTime()), m_modified(QDateTime()),
      m_context(ctx)
{
}

TicketPrivate::TicketPrivate(const TicketPrivate &other)
    : Ticket(), m_id(other.m_id), m_created(other.m_created), m_modified(other.m_modified),
      m_fields(other.m_fields), m_context(other.m_context)
{
}

TicketPrivate::~TicketPrivate()
{
    clearChangesets();
    clearActions();
    delete m_context;
}

int TicketPrivate::id() const
{
    return m_id;
}

void TicketPrivate::setId(int id)
{
    m_id = id;
}


void TicketPrivate::refresh()
{
    if (m_context)
        m_context->refreshTicket(this);
}

QDateTime TicketPrivate::created() const
{
    return m_created;
}

QDateTime TicketPrivate::modified() const
{
    return m_modified;
}

QVariant TicketPrivate::fieldByName(const QString &fieldName) const
{
    return m_fields.value(fieldName);
}

bool TicketPrivate::containsField(const QString &fieldName) const
{
    return m_fields.contains(fieldName);
}

QStringList TicketPrivate::fieldNames() const
{
    return m_fields.keys();
}

QVariantMap TicketPrivate::fields() const
{
    return m_fields;
}

TicketEditor *TicketPrivate::editor()
{
    return new TicketEditorPrivate(this);
}

void TicketPrivate::doUpdateNotify()
{
    emit updated(this);
}

void TicketPrivate::save(const QString &comment)
{
    if (m_context)
        m_context->storeTicket(this, comment);
}

void TicketPrivate::setHistory(QList<TicketChangeset *> history)
{
    if (m_changesets.count() > 0) {
        qDeleteAll(m_changesets);
        m_changesets.clear();
    }
    m_changesets << history;
    emit historyLoaded();
}

void TicketPrivate::setAvailableActions(QList<TicketAction *> actions)
{
    if (m_actions.count() > 0) {
        qDeleteAll(m_actions);
        m_actions.clear();
    }
    m_actions << actions;
    emit actionsLoaded();
}


void TicketPrivate::loadHistory()
{
    if (m_context)
        m_context->updateHistory(this);
}

void TicketPrivate::loadAvailableActions()
{
    if (m_context)
        m_context->updateActions(this);
}

QList<TicketAction *> TicketPrivate::availableActions() const
{
    return m_actions;
}

QList<TicketChangeset *> TicketPrivate::history() const
{
    return m_changesets;
}

Ticket * TicketPrivate::dup()
{
    TicketPrivate *tmp = new TicketPrivate(*this);
    return tmp;
}

void TicketPrivate::clearChangesets()
{
    qDeleteAll(m_changesets);
    m_changesets.clear();
}

void TicketPrivate::clearActions()
{
    qDeleteAll(m_actions);
    m_actions.clear();
}

QDebug operator<<(QDebug debug, const Ticket *ticket)
{
    debug << "TICKET (ID: "<< ticket->id() <<"): modified: "
             << ticket->modified().toString() << " created: "
             << ticket->created().toString();
    debug << ticket->fieldNames();
    return debug;
}

QDebug operator<<(QDebug debug, const TicketChangeset *changeset)
{
    debug << "Changeset by " << changeset->author() << " at "
          << changeset->timestamp().toString() << "\n";
    FieldMap changedFields = changeset->changedFields();
    foreach (QString field, changedFields.keys())
        debug << "field: " << field << " => " << changedFields.value(field).value << "\n";
    return debug;
}





